
package com.jf.cloud.order.controller.platform;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.core.util.StrUtil;
import com.jf.cloud.api.delivery.feign.DeliveryFeignClient;
import com.jf.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.jf.cloud.api.multishop.vo.ShopDetailVO;
import com.jf.cloud.api.order.constant.OrderStatus;
import com.jf.cloud.api.product.feign.CategoryFeignClient;
import com.jf.cloud.api.supplier.feign.SupplierDetailFeignClient;
import com.jf.cloud.api.supplier.vo.SupplierApiDetailVO;
import com.jf.cloud.common.order.constant.DeliveryType;
import com.jf.cloud.common.order.vo.*;
import com.jf.cloud.api.user.feign.UserFeignClient;
import com.jf.cloud.api.user.vo.UserApiVO;
import com.jf.cloud.api.vo.EsPageVO;
import com.jf.cloud.common.database.dto.PageDTO;
import com.jf.cloud.common.order.constant.OrderActivityType;
import com.jf.cloud.common.order.dto.OrderSearchDTO;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.util.ExcelUtil;
import com.jf.cloud.order.constant.Constant;
import com.jf.cloud.order.model.Order;
import com.jf.cloud.order.model.OrderAddr;
import com.jf.cloud.order.service.OrderAddrService;
import com.jf.cloud.order.service.OrderExcelService;
import com.jf.cloud.order.service.OrderSelfStationService;
import com.jf.cloud.order.service.OrderService;
import com.jf.cloud.order.vo.OrderExcelVO;
import com.jf.cloud.order.vo.OrderOverviewVO;
import com.jf.cloud.order.vo.ScoreOrderExcelVO;
import io.swagger.v3.oas.annotations.Operation;
import ma.glasnost.orika.MapperFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 平台订单管理
 * @author zz
 * @date: 2021-05-06 16:15:15
 */
@RestController("platformOrderController")
@RequestMapping("/p/order")
public class OrderController {
    private static final Logger logger = LoggerFactory.getLogger(OrderController.class);

    @Value("${jfcloud.expose.operation.auth:}")
    private Boolean permission;

    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderExcelService orderExcelService;
    @Autowired
    private OrderAddrService orderAddrService;
    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private UserFeignClient userFeignClient;
    @Autowired
    private OrderSelfStationService orderSelfStationService;
    @Autowired
    private SupplierDetailFeignClient supplierDetailFeignClient;
    @Autowired
    private ShopDetailFeignClient shopDetailFeignClient;

    /**
     * 分页获取
     */
    @GetMapping("/page")
    public ServerResponseEntity<EsPageVO<EsOrderVO>> page(@ParameterObject OrderSearchDTO orderSearchDTO) {
        if (Objects.equals(orderSearchDTO.getStatus(), OrderStatus.PAYED.value())) {
            orderSearchDTO.setWaitPurchase(0);
        }
        if (Objects.equals(orderSearchDTO.getStatus(), Constant.WAIT_PURCHASES_STATUS)) {
            orderSearchDTO.setStatus(OrderStatus.PAYED.value());
            orderSearchDTO.setWaitPurchase(1);
        }
        // 判断处理供应商名称和店铺名称,防止因改名而导致的数据错误
        Map<Long, String> shopNameMap = orderService.checkShopName(orderSearchDTO);
        Map<Long, String> supplierNameMap = orderService.checkSupplierName(orderSearchDTO);
        EsPageVO<EsOrderVO> orderPage = orderService.orderPage(orderSearchDTO);
        if (BooleanUtil.isFalse(permission)) {
            logger.info("隐藏手机号");
            for (EsOrderVO esOrderVO : orderPage.getList()) {
                if (StrUtil.isNotBlank(esOrderVO.getMobile())) {
                    esOrderVO.setMobile(PhoneUtil.hideBetween(esOrderVO.getMobile()).toString());
                }
            }
        }
        // 数据准备
        List<Long> userIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<Long> stationOrderIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<Long> supplierIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
        List<Long> shopIds = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (EsOrderVO orderVO : orderPage.getList()) {
            userIds.add(orderVO.getUserId());
            stationOrderIds.add(orderVO.getOrderId());
            supplierIds.add(orderVO.getSupplierId());
            shopIds.add(orderVO.getShopId());
        }
        // 查询用户信息
        List<UserApiVO> userList = userFeignClient.getUserByUserIds(userIds).getData();
        Map<Long, String> userMap = userList.stream().collect(Collectors.toMap(UserApiVO::getUserId, UserApiVO::getNickName));
        // 查找自提订单对应自提人信息
        Map<Long, OrderSelfStationVO> selfStationMap = new HashMap<>(16);
        if (CollUtil.isNotEmpty(stationOrderIds)) {
            List<OrderSelfStationVO> selfStationVOList = orderSelfStationService.listSelfStationByOrderIds(stationOrderIds);
            selfStationMap = selfStationVOList.stream().collect(Collectors.toMap(OrderSelfStationVO::getOrderId, x -> x));
        }
        if (CollUtil.isEmpty(supplierNameMap) && CollUtil.isNotEmpty(supplierIds)) {
            logger.info("补充供应商订单消息");
            List<SupplierApiDetailVO> supplierList = supplierDetailFeignClient.listBySupplierIds(supplierIds).getData();
            supplierNameMap.putAll(supplierList.stream().collect(Collectors.toMap(SupplierApiDetailVO::getSupplierId, SupplierApiDetailVO::getSupplierName)));
        }
        if (CollUtil.isEmpty(shopNameMap)) {
            logger.info("补充店铺订单消息");
            List<ShopDetailVO> shopList = shopDetailFeignClient.listByShopIds(shopIds).getData();
            shopNameMap.putAll(shopList.stream().collect(Collectors.toMap(ShopDetailVO::getShopId, ShopDetailVO::getShopName)));
        }
        for (EsOrderVO orderVO : orderPage.getList()) {
            orderVO.setUserName(null == userMap.get(orderVO.getUserId()) ? "*用户已注销*" : userMap.get(orderVO.getUserId()));
            orderVO.setShopName(null == shopNameMap.get(orderVO.getShopId()) ? null : shopNameMap.get(orderVO.getShopId()));
            orderVO.setSupplierName(null == supplierNameMap.get(orderVO.getSupplierId()) ? null : supplierNameMap.get(orderVO.getSupplierId()));
            // 补充自提人信息
            OrderSelfStationVO stationVO = selfStationMap.get(orderVO.getOrderId());
            if (stationVO != null) {
                orderVO.setConsignee(stationVO.getStationUserName());
                orderVO.setMobile(stationVO.getStationUserMobile());
            }
            //赠品处理
            Map<Long, List<EsOrderItemVO>> map = orderVO.getOrderItems().stream().filter(s -> Objects.equals(s.getActivityType(), OrderActivityType.GIVEAWAY.value()))
                    .collect(Collectors.groupingBy(EsOrderItemVO::getActivityId));
            // 如果没有赠品，就不需要处理
            if (MapUtil.isEmpty(map)) {
                continue;
            }
            // 将赠品放到对应的主订单项中
            Iterator<EsOrderItemVO> iterator = orderVO.getOrderItems().iterator();
            while (iterator.hasNext()) {
                EsOrderItemVO myOrderItemDto = iterator.next();
                // 移除赠品的订单项，进入下一个循环
                if (Objects.equals(myOrderItemDto.getActivityType(), OrderActivityType.GIVEAWAY.value())) {
                    iterator.remove();
                    continue;
                }
                // 主订单项插入赠品订单项
                if (map.containsKey(myOrderItemDto.getOrderItemId())) {
                    myOrderItemDto.setGiveawayList(map.get(myOrderItemDto.getOrderItemId()));
                }
            }
        }
        return ServerResponseEntity.success(orderPage);
    }

    /**
     * 获取信息
     */
    @GetMapping("/order_info/{orderId}")
    public ServerResponseEntity<OrderVO> info(@ParameterObject @PathVariable("orderId") Long orderId) throws UnsupportedEncodingException {
        // 订单和订单项
        Order order = orderService.getOrderAndOrderItemData(orderId, null);
        OrderVO orderVO = mapperFacade.map(order, OrderVO.class);
        //如果是自提订单就没有收货地址
        if(!Objects.equals(orderVO.getDeliveryType(), DeliveryType.STATION.value())){
            // 详情用户收货地址
            OrderAddr orderAddr = orderAddrService.getById(order.getOrderAddrId());
            if (BooleanUtil.isFalse(permission) && Objects.nonNull(orderAddr)){
                logger.info("隐藏手机号中间四位");
                orderAddr.setMobile(PhoneUtil.hideBetween(orderAddr.getMobile()).toString());
            }
            orderVO.setOrderAddr(mapperFacade.map(orderAddr, OrderAddrVO.class));
        }
        // 处理下赠品
        //List<OrderItemVO> orderItemDbList = orderItemService.listOrderItemAndLangByOrderId(orderId);
        // 获取赠品map
        Map<Long, List<OrderItemVO>> giveawayMap = orderVO.getOrderItems().stream().filter(item -> Objects.equals(item.getActivityType(), OrderActivityType.GIVEAWAY.value()))
                .collect(Collectors.groupingBy(OrderItemVO::getActivityId));
        List<OrderItemVO> orderItemDbList = new ArrayList<>();
        for (OrderItemVO orderItem : orderVO.getOrderItems()) {
            // 赠品订单项不需要进行处理
            if(Objects.equals(orderItem.getActivityType(), OrderActivityType.GIVEAWAY.value())){
                continue;
            }
            // 放入赠品
            if(giveawayMap.containsKey(orderItem.getOrderItemId())){
                orderItem.setGiveawayList(giveawayMap.get(orderItem.getOrderItemId()));
            }
            orderItemDbList.add(orderItem);
        }
        orderVO.setOrderItems(orderItemDbList);
        // 补充自提点信息
        if (order.getDeliveryType() != null
                && DeliveryType.STATION.value().equals(order.getDeliveryType())) {
            logger.info("自提订单，补充自提点信息");
            OrderSelfStationVO stationVO = orderSelfStationService.getStationByOrderId(orderId);
            orderVO.setOrderSelfStationVO(stationVO);
        }
        orderVO.setOrderItems(orderItemDbList);
        return ServerResponseEntity.success(orderVO);
    }


    @GetMapping("/get_order_by_userId")
    @Operation(summary = "分页获取某个用户的订单数据" , description = "分页获取某个用户的订单数据")
    public ServerResponseEntity<EsPageVO<EsOrderVO>> getOrderByUserId(PageDTO pageDTO, @ParameterObject String userId){
        EsPageVO<EsOrderVO> pages = orderService.pageByUserId(pageDTO,userId);
        return ServerResponseEntity.success(pages);
    }

    @GetMapping("/sold_excel")
    @Operation(summary = "导出excel" , description = "导出订单excel")
    public ServerResponseEntity<Void> orderSoldExcel(HttpServletResponse response, @ParameterObject OrderSearchDTO orderSearchDTO){
        List<OrderExcelVO> list = orderExcelService.excelOrderList(orderSearchDTO);
        ExcelUtil.soleExcel(response, list, OrderExcelVO.EXCEL_NAME, OrderExcelVO.MERGE_ROW_INDEX, OrderExcelVO.MERGE_COLUMN_INDEX, OrderExcelVO.class);
        return ServerResponseEntity.success();
    }


    @GetMapping("/score_sold_excel")
    @Operation(summary = "积分订单导出excel" , description = "积分订单导出excel")
    public ServerResponseEntity<Void> scoreOrderSoldExcel(HttpServletResponse response, @ParameterObject OrderSearchDTO orderSearchDTO){
        // 需要合并的列数组
        List<OrderExcelVO> list = orderExcelService.excelOrderList(orderSearchDTO);
        List<ScoreOrderExcelVO> scoreOrderExcelVOS = mapperFacade.mapAsList(list, ScoreOrderExcelVO.class);

        ExcelUtil.soleExcel(response, scoreOrderExcelVOS, ScoreOrderExcelVO.EXCEL_NAME, ScoreOrderExcelVO.MERGE_ROW_INDEX, ScoreOrderExcelVO.MERGE_COLUMN_INDEX, ScoreOrderExcelVO.class);
        return ServerResponseEntity.success();
    }

    @GetMapping("/count_primary_category")
    @Operation(summary = "根据一级分类获取订单金额和数量" , description = "根据一级分类获取订单金额和数量")
    public ServerResponseEntity<List<Map<String,Object>>> countPrimaryCategory(@ParameterObject OrderSearchDTO orderSearchDTO){

        return ServerResponseEntity.success(orderService.countPrimaryCategory(orderSearchDTO.getStartTime(),orderSearchDTO.getEndTime()));
    }

    @GetMapping("/sum_group_month")
    @Operation(summary = "按月份分组统计" , description = "按月份分组统计")
    public ServerResponseEntity<List<OrderOverviewVO>> sumGroupByMonth(@ParameterObject OrderSearchDTO orderSearchDTO){
        return ServerResponseEntity.success(orderService.sumGroupByMonth(orderSearchDTO.getStartTime(),orderSearchDTO.getEndTime()));
    }


    @GetMapping("/sum_group_area")
    @Operation(summary = "按地区分组统计" , description = "按地区分组统计")
    public ServerResponseEntity<List<Map<String,Object>>> sumGroupByArea(@ParameterObject OrderSearchDTO orderSearchDTO){
        return ServerResponseEntity.success(orderService.sumGroupByArea(orderSearchDTO));
    }
}
